package myPack;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Vector;

import javax.swing.JTextArea;

import org.farng.mp3.AbstractMP3Tag;
import org.farng.mp3.MP3File;
import org.farng.mp3.id3.AbstractID3v2;
import org.farng.mp3.id3.ID3v1;

public class Song {
	private String filename = "";
	private String title = "";
	private String interpreter = "";
	private String album = "";
	private String md5 = "";
	private File file = null;
	private AbstractID3v2 tag_v2;
	private ID3v1 tag_v1;
	private AbstractMP3Tag tag = null;
	
	private PropertyChangeSupport changes = new PropertyChangeSupport(this);
	
	public Song(File file) {
		this.file = file;
		this.filename = file.getName();
		System.out.print("Checking File " + this.file.getAbsolutePath() + "...");

		try {
			MP3File mp3 = new MP3File(this.file);
			this.tag = mp3.getID3v2Tag();
			if (this.tag == null) {
				this.tag = mp3.getID3v1Tag();
			}
			if (this.tag == null) {
				System.out.print(" -no tags found.\n");
			} else {
				System.out.print(" -tags found.\n");
				this.title = this.tag.getSongTitle();
				this.interpreter = this.tag.getLeadArtist();
				this.album = this.tag.getAlbumTitle();
				//modify this to take the actual file as input for md5
				byte[] bArr = {(byte)5, (byte)6};
				this.md5 = this.calcMD5(bArr);
			}
		} catch (Exception e) {
			Main.LOGGER.warning("**Exception!\n" + e);
			System.out.println(this.filename);
			e.printStackTrace();
		}
	}
	
	public String calcMD5(byte[] data) {
		MessageDigest md = null;
		try {
			md = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		byte[] hash = md.digest(data);
		 
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < hash.length; ++i) {
		    sb.append(Integer.toHexString(
		             (hash[i] & 0xFF) | 0x100
		         ).toLowerCase().substring(1,3)
		     );
		}
		return sb.toString();
	}

	public void listTags(JTextArea area) {
		StringBuffer text = new StringBuffer();
		text.append("Listing tags...\n\n");
		text.append("Filename: " + this.filename +"\n");
		
		if (this.tag != null) {
			text.append("Tags:\n");
			text.append("Interpreter: " + this.tag.getLeadArtist() + "\n");
			text.append("Album: " + this.tag.getAlbumTitle()+ "\n");
			text.append("Titel: " + this.tag.getSongTitle() + "\n\n");
		}
		
		if (this.tag_v2 != null) {
			text.append("ID3v2_4 Tags:\n");
			text.append("Interpreter: " + this.tag_v2.getLeadArtist() + "\n");
			text.append("Album: " + this.tag_v2.getAlbumTitle()+ "\n");
			text.append("Titel: " + this.tag_v2.getSongTitle() + "\n\n");
		}
		
		if (this.tag_v1 != null) {
			text.append("ID3v1 Tags:\n");
			text.append("Interpreter: " + this.tag_v1.getLeadArtist() + "\n");
			text.append("Album: " + this.tag_v1.getAlbumTitle()+ "\n");
			text.append("Titel: " + this.tag_v1.getSongTitle());
		}
		
		if (this.tag == null) {
			text.append("Didn't find any tags!");
		}
		
		area.setText(text.toString());
	}
	
	
	public void setTitle(String title) {
		String oldTitle = this.title;
		this.title = title;
		changes.firePropertyChange("title", oldTitle, title);
	}
	
	public void setInterpreter(String interpreter) {
		String oldInterpreter = this.interpreter;
		this.interpreter = interpreter;
		changes.firePropertyChange("interpreter", oldInterpreter, interpreter);
	}
	
	public void setAlbum(String album) {
		this.album = album;
	}
	
	public String getTitle() {
		return this.title;
	}
	
	public String getInterpreter() {
		return this.interpreter;
	}
	
	public String getAlbum() {
		return this.album;
	}
	
	public void addPropertyChangeListener(PropertyChangeListener l) {
		changes.addPropertyChangeListener(l);
	}
	
	public void removePropertyChangeListener(PropertyChangeListener l) {
		changes.addPropertyChangeListener(l);
	}
	
	public String getMD5() {
		return this.md5;
	}
	
	public Vector<Object> getVector() {
		Vector<Object> vec = new Vector<>();
		vec.add(this.title);
		vec.add(this.interpreter);
		vec.add(this.filename);
		vec.add(this.md5);
		return vec;
	}
	
}
